home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / cyberxxxsrc / decoder / txt / decodeimaadpcm.c < prev    next >
C/C++ Source or Header  |  1999-02-08  |  3KB  |  148 lines

  1. /*
  2. sc:c/sc opt txt/DecodeIMAADPCM.c
  3. */
  4.  
  5. #include "Decode.h"
  6. #include "ADPCM.h"
  7.  
  8. struct IMAADPCMData {
  9.   uchar downScale;
  10. };
  11.  
  12. /* /// "DecodeIMAADPCM4Mono()" */
  13. __asm ulong DecodeIMAADPCM4Mono(REG(a0) uchar *from,
  14.                                 REG(a1) uchar *toL,
  15.                                 REG(a2) uchar *toR,
  16.                                 REG(d0) ulong size,
  17.                                 REG(a3) struct IMAADPCMData *spec)
  18. {
  19.   long todo=(size/0x40*0x22);
  20.   ulong decoded=0;
  21.  
  22.   ulong blockCnt=0x40;
  23.   uchar downScale=spec->downScale;
  24.  
  25.   while (todo>0) {
  26.     long valPred;
  27.     long index;
  28.     long step;
  29.     ulong n;
  30.     uchar firstNibble;
  31.  
  32.     valPred=get16(from);
  33.     index=valPred & 0x7f;
  34.     if (index>88) index=88;
  35.     valPred &= 0xff80;
  36.     if (valPred & 0x8000) valPred-=0x10000;
  37.  
  38.     step=stepSizeTable[index];
  39.     todo-=2;
  40.     if (todo<=0) {decoded=0; goto ima4MonoDecodeExit;}
  41.  
  42.     firstNibble=1;
  43.     for(n=0; n<blockCnt; n++) {
  44.       ulong loNibble, hiNibble;
  45.  
  46.       if (firstNibble) {
  47.         loNibble=*from++;
  48.         hiNibble=(loNibble>>4) & 0x0f;
  49.         loNibble &= 0x0f;
  50.         todo--;
  51.         if (todo<0) goto ima4MonoDecodeExit;
  52.         if (downScale)
  53.           n++;
  54.         else
  55.           firstNibble=0;
  56.       } else {
  57.         loNibble=hiNibble;
  58.         firstNibble=1;
  59.       }
  60.       calcDVI(valPred,loNibble,index,step);
  61.       *toL++=(uchar)(valPred>>8);
  62.       decoded++;
  63.     }
  64.   }
  65.  
  66. ima4MonoDecodeExit:
  67.   return decoded;
  68. }
  69. /* \\\ */
  70.  
  71. /* /// "DecodeIMAADPCM4Stereo()" */
  72. __asm ulong DecodeIMAADPCM4Stereo(REG(a0) uchar *from,
  73.                                   REG(a1) uchar *toL,
  74.                                   REG(a2) uchar *toR,
  75.                                   REG(d0) ulong size,
  76.                                   REG(a3) struct IMAADPCMData *spec)
  77. {
  78.   long todo=((size>>1)/0x40*0x22);
  79.   ulong decoded=0;
  80.  
  81.   ulong blockCnt=0x40;
  82.   uchar downScale=spec->downScale;
  83.   uchar *fromLeft=from;
  84.   uchar *fromRight=from+0x22;
  85.  
  86.   while (todo>0) {
  87.     long lValPred, rValPred;
  88.     long lIndex, rIndex;
  89.     long lStep, rStep;
  90.     ulong n;
  91.     uchar firstNibble;
  92.  
  93.     lValPred=get16(fromLeft);
  94.     lIndex=lValPred & 0x7f;
  95.     if (lIndex>88) lIndex=88;
  96.     lValPred &= 0xff80;
  97.     if (lValPred & 0x8000) lValPred-=0x10000;
  98.     lStep=stepSizeTable[lIndex];
  99.  
  100.     rValPred=get16(fromRight);
  101.     rIndex=rValPred & 0x7f;
  102.     if (rIndex>88) rIndex=88;
  103.     rValPred &= 0xff80;
  104.     if (rValPred & 0x8000) rValPred-=0x10000;
  105.     rStep=stepSizeTable[rIndex];
  106.  
  107.     todo-=2;
  108.     if (todo<=0) {decoded=0; goto ima4StereoDecodeExit;}
  109.  
  110.     firstNibble=1;
  111.     for(n=0; n<blockCnt; n++) {
  112.       ulong loNibbleL, hiNibbleL;
  113.       ulong loNibbleR, hiNibbleR;
  114.  
  115.       if (firstNibble) {
  116.         loNibbleL=*fromLeft++;
  117.         hiNibbleL=(loNibbleL>>4) & 0x0f;
  118.         loNibbleL &= 0x0f;
  119.         loNibbleR=*fromRight++;
  120.         hiNibbleR=(loNibbleR>>4) & 0x0f;
  121.         loNibbleR &= 0x0f;
  122.         todo--;
  123.         if (todo<0) goto ima4StereoDecodeExit;
  124.         if (downScale)
  125.           n++;
  126.         else
  127.           firstNibble=0;
  128.       } else {
  129.         loNibbleL=hiNibbleL;
  130.         loNibbleR=hiNibbleR;
  131.         firstNibble=1;
  132.       }
  133.       calcDVI(lValPred,loNibbleL,lIndex,lStep);
  134.       *toL++=(uchar)(lValPred>>8);
  135.       calcDVI(rValPred,loNibbleR,rIndex,rStep);
  136.       *toR++=(uchar)(rValPred>>8);
  137.       decoded++;
  138.     }
  139.     fromLeft+=0x22;
  140.     fromRight+=0x22;
  141.   }
  142.  
  143. ima4StereoDecodeExit:
  144.   return decoded;
  145. }
  146. /* \\\ */
  147.  
  148.